//
// Created by ZYZ on 2020/6/15.
//
#include <stdio.h>
#include "../../include/define.h"
#include "linear_stack.h"
#include "stack_use4_maze.h"
#include "../common/log.h"

#ifdef SELEMTYPE_MAZE

//判断当前块是否可通过
Status Pass(MazeType MyMaze, PosType curPos) {
    if (MyMaze.arr[curPos.r][curPos.c] == ' ')
        return OK;                                        // 如果当前位置是可以通过，返回1
    else
        return ERROR;                                     // 其它情况返回0
}

//下一个位置
PosType NextPos(PosType curPos, int dir) {
    PosType returnPos;
    switch (dir) {
        case 1: //东
            returnPos.r = curPos.r;
            returnPos.c = curPos.c + 1;
            break;
        case 2: //南
            returnPos.r = curPos.r + 1;
            returnPos.c = curPos.c;
            break;
        case 3: //西
            returnPos.r = curPos.r;
            returnPos.c = curPos.c - 1;
            break;
        case 4://北
            returnPos.r = curPos.r - 1;
            returnPos.c = curPos.c;
            break;
    }
    return returnPos;
}

//迷宫解密函数
Status MazePath(MazeType &maze, PosType start, PosType end) {

    SqStack stack;                                          //路径的存储栈
    PosType curpos;                                         //当前位置坐标
    int curstep;                                            //探索步骤
    SElemType stack_cur_ele;                                //当前坐标块

    InitStack(stack);                                    //初始化栈
    curpos = start;                                         //初始当前位置为入口
    curstep = 1;
    do {
        printf("curpos = (%d,%d)",curpos.r,curpos.c);

        if (Pass(maze, curpos)) {                           //当前位置可通过，即是未曾走到过的坐标 (因为走过的都变为了 *)
            print("该 curpos 可以 Pass \n");
            maze.arr[curpos.r][curpos.c] = '*';             //留下足迹
            stack_cur_ele.direction = 1;
            stack_cur_ele.order_num = curstep;
            stack_cur_ele.seat = curpos;

            printf("Pass, 开始 Push 元素，该元素当前坐标为: (%d,%d) \n",stack_cur_ele.seat.r,stack_cur_ele.seat.c);
            Push(stack, stack_cur_ele);                  //加入路径

            if (curpos.r == end.r && curpos.c == end.c)     //到达终点（出口）
                return OK;
            curpos = NextPos(curpos, 1);                //下一位置是当前位置的东邻
            curstep++;                                      //探索下一步
        } else {                                            //当前位置不能通过
            printf("该 curpos 不能 Pass,元素内容为: %c \n",maze.arr[curpos.r][curpos.c]);

            if (!StackEmpty(stack)) {

                printf("else 开始 Pop 元素, 该元素当前坐标为 (%d,%d) \n",stack_cur_ele.seat.r,stack_cur_ele.seat.c);
                Pop(stack, stack_cur_ele);           //先 Pop 一次获取当前的元素，如果该元素的四个方向都不行则再 Pop 一次(丢弃该结点)，否则如果有一个方向可以则再 push 一下

                while (stack_cur_ele.direction == 4 && !StackEmpty(stack)) {
                    maze.arr[stack_cur_ele.seat.r][stack_cur_ele.seat.c] = '!';
                    printf("direction == 4，开始 Pop 元素, 该元素当前坐标为 (%d,%d) \n",stack_cur_ele.seat.r,stack_cur_ele.seat.c);
                    Pop(stack, stack_cur_ele);        // 留下不能通过的标记，并退回一步
                    printf("direction == 4, Pop 完获取到的栈顶元素坐标为 (%d,%d) \n",stack_cur_ele.seat.r,stack_cur_ele.seat.c);
                }

                if (stack_cur_ele.direction < 4) {          //还有其他方向没有探索完           //Push 同一个元素是否执行了多次？？
                    stack_cur_ele.direction++;              //每次 +1，即顺时针 东南西北 探索
                    printf("开始向下一个方向探索, 开始 Push 元素，该元素当前坐标为: (%d,%d) \n",stack_cur_ele.seat.r,stack_cur_ele.seat.c);
                    Push(stack, stack_cur_ele);          //换下一个方向探索
                    curpos = NextPos(stack_cur_ele.seat, stack_cur_ele.direction);         // 当前位置设为新方向的相邻块
                    printf("获取到新的元素坐标为: (%d,%d) \n",curpos.r,curpos.c);
                }
            }
        }
    } while (!StackEmpty(stack));
    return ERROR;
}

#endif